﻿#include "MyApp.h"
#include <QDebug>
#include <QDir>
#include <QSettings>
#include <QFile>
#include <QPixmap>
#include <QStandardPaths>

#include "CustomWidget.h"

// 应用程序配置目录
QString MyApp::m_strAppPath         = "./";
QString MyApp::m_strDataPath        = "";
QString MyApp::m_strConfPath        = "";
QString MyApp::s_strDatabasePath    = "";
QString MyApp::m_strUsersPath       = "";
QString MyApp::m_strHeadPath        = "";
QString MyApp::m_strSoundPath       = "";
QString MyApp::m_strRecvPath        = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/Dreamgo/FileRecv/";
bool    MyApp::m_bPlaySound         = true;
bool    MyApp::m_bShowExitDlg       = true;
bool    MyApp::m_bMainWindowHide    = true;
// 配置文件
QString MyApp::m_strIniFile         = "config.ini";
QString MyApp::m_strUsersFile       = "LoginAccountList.dat";
// 服务器相关配置,初次载入程序的配置
QString MyApp::m_strHostAddr        = "118.24.206.58";
int     MyApp::m_nMsgPort           = 20000;
QString MyApp::m_strFileServerAddr  = "118.24.206.58";
int   MyApp::m_nFileSeverPort       = 20001;

QString MyApp::m_strUserName        = "";
QString MyApp::m_strUserPwd         = "";
QString MyApp::m_strUserCfgFile     = "";

MyApp::MyApp()
{

}

//初始化
void MyApp::InitApp(const QString &appPath)
{

    qDebug() << appPath;
    m_strAppPath        = appPath + "/";
    m_strDataPath       = m_strAppPath  + "Data/";
    m_strSoundPath      = m_strDataPath + "Sound/";
    m_strConfPath       = m_strDataPath + "Conf/";
    m_strIniFile        = m_strConfPath + "config.ini";
    m_strUsersPath      = m_strDataPath + "Users/";
    m_strUsersFile      = m_strUsersPath + m_strUsersFile;
    m_strHeadPath       = m_strDataPath + "Head/";
    m_strUserCfgFile    = m_strUsersPath + m_strUserName + "/" + m_strUserName + ".cfg";
    s_strDatabasePath   = m_strUsersPath + m_strUserName + "Chatlog/";

    //注冊异常捕获函数
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);

    // 检查目录、文件
    CheckDirs();

    // 创建配置文件
    CreatorSettingFile();

    //检查头像文件
    UnPackHeasicons();

    //检查声音文件
    CheckSound();

    // 加载系统配置
    ReadSettingFile();
}

/**
  @brief:MyApp::CreatorSettingFile
  *创建配置文件
  @Author:
**/
void MyApp::CreatorSettingFile()
{
    // 写入配置文件
    QSettings settings(m_strIniFile, QSettings::IniFormat);
    QString strGroups = settings.childGroups().join("");
    if (!QFile::exists(m_strIniFile) || (strGroups.isEmpty()))
    {
        /*其他配置*/
        settings.beginGroup("Server");
        settings.setValue("HostAddr", m_strHostAddr);
        settings.setValue("MsgPort",  m_nMsgPort);
        settings.setValue("FileServerAddr", m_strFileServerAddr);
        settings.setValue("FileServerPort",  m_nFileSeverPort);
        settings.endGroup();
        settings.sync();        //马上写入配置文件
    }
}
/**
  @brief:MyApp::ReadSettingFile
  读配置文件，加载系统配置到变量
  */
void MyApp::ReadSettingFile()
{
    //网络配置
    QSettings settings(m_strIniFile, QSettings::IniFormat);
    settings.beginGroup("Server");
    m_strHostAddr = settings.value("HostAddr").toString();
    m_nMsgPort    = settings.value("MsgPort").toInt();
    m_strFileServerAddr = settings.value("FileServerAddr").toString();
    m_nFileSeverPort = settings.value("FileServerPort").toInt();
    settings.endGroup();
}
/**
 * @brief:MyApp::SetSettingFile 修改配置文件
 * @param:group 组
 * @param:key   键
 * @param:value 值
 * @Author:
 **/
void MyApp::SetSettingFile(const QString& filename, const QString &group, const QString &key, const QVariant &value)
{
    QSettings settings(filename, QSettings::IniFormat);
    settings.beginGroup(group);
    settings.setValue(key, value);
    settings.sync();
    //ReadSettingFile();
}
/**
 * @brief:MyApp::SetSettingFile 读取配置文件
 * @param:group 组
 * @param:key   键
 * @param:value default值
 * @Author:
 **/
QVariant MyApp::GetSettingKeyValue(const QString& filename, const QString &group, const QString &key, const QVariant &value)
{
    QSettings settings(filename, QSettings::IniFormat);
    settings.beginGroup(group);
    return settings.value(key, value);
}

// 检查目录
void MyApp::CheckDirs()
{
    // 数据文件夹
    QDir dir(m_strDataPath);
    if(!dir.exists())
    {
        dir.mkdir(m_strDataPath);       //FIXME:check ret?
    }

    //配置文件目录
    dir.setPath(m_strConfPath);
    if(!dir.exists())
    {
        dir.mkdir(m_strConfPath);       //FIXME:check ret?
    }

    //声音文件目录
    dir.setPath(m_strSoundPath);
    if(!dir.exists())
    {
        dir.mkdir(m_strSoundPath);       //FIXME:check ret?
    }

    //用户信息文件目录
    dir.setPath(m_strUsersPath);
    if(!dir.exists())
    {
        dir.mkdir(m_strUsersPath);
    }

    //历史用户登录信息保存文件
    QFile file(m_strUsersFile);
    if(!file.exists())
    {
        if(!file.open(QIODevice::WriteOnly))
        {
            qDebug() << "用户登录信息保存文件打开失败";
        }
    }

    /*
    //用户配置文件
    file.setFileName(m_strUserCfgFile);
    if(!file.exists())
    {
        if(!file.open(QIODevice::WriteOnly))
        {
            qDebug() << "用户配置文件打开失败";
        }
    }
*/
    //系统默认头像目录
    dir.setPath(m_strHeadPath);
    if(!dir.exists())
    {
        dir.mkdir(m_strHeadPath);
    }

    //默认文件接收路径
    dir.setPath(m_strRecvPath);
    if(!dir.exists())
    {
        dir.mkpath(m_strHeadPath);
    }
}

/**
 * @brief WidgetHead::UnPackHeasicons
 * 解压头像文件
 */
void MyApp::UnPackHeasicons()
{
    for (int i = 0; i < 35; i++) {
        QString strHead = MyApp::m_strHeadPath + QString("%1.png").arg(i);
        if (!QFile::exists(strHead)) {
            QPixmap pixmap(QString(":/Images/resource/head/%1.png").arg(i));
            pixmap.save(MyApp::m_strHeadPath + QString("%1.png").arg(i));
        }
    }
}

/**
 * @brief MyApp::CheckSound
 * 音频文件检测
 */
void MyApp::CheckSound()
{
    if (!QFile::exists(MyApp::m_strSoundPath + "Global.wav")) {
        QFile::copy(":/sound/sound/Global.wav", MyApp::m_strSoundPath + "Global.wav");
    }

    if (!QFile::exists(MyApp::m_strSoundPath + "msg.wav")) {
        QFile::copy(":/sound/sound/msg.wav", MyApp::m_strSoundPath + "msg.wav");
    }

    if (!QFile::exists(MyApp::m_strSoundPath + "system.wav")) {
        QFile::copy(":/sound/sound/system.wav", MyApp::m_strSoundPath + "system.wav");
    }
}

//保存配置
void MyApp::SaveConfig()
{
    QSettings settings(m_strIniFile, QSettings::IniFormat);

    /*网络配置*/
    settings.beginGroup("Server");
    settings.setValue("HostAddr", m_strHostAddr);
    settings.setValue("MsgPort",  m_nMsgPort);
    settings.setValue("FileServerAddr", m_strFileServerAddr);
    settings.setValue("FileServerPort",  m_nFileSeverPort);
    settings.endGroup();
    settings.sync();
}

//程式异常捕获
LONG MyApp::ApplicationCrashHandler(EXCEPTION_POINTERS *pException)
{
    /*
     ***保存数据代码***
     */
   QString Str = QDateTime::currentDateTime().toString("yyyy-MM-dd-hhmmss")+QString(".dmp");

   HANDLE hDumpFile = CreateFile(reinterpret_cast<LPCWSTR>(Str.data()), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
   if( hDumpFile != INVALID_HANDLE_VALUE){
       //Dump信息
       MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
       dumpInfo.ExceptionPointers = pException;
       dumpInfo.ThreadId = GetCurrentThreadId();
       dumpInfo.ClientPointers = TRUE;
       //写入Dump文件内容
       MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, nullptr, nullptr);
   }

    //这里弹出一个错误对话框并退出程序
    EXCEPTION_RECORD* record = pException->ExceptionRecord;

    QString errCode(QString::number(record->ExceptionCode,16)),errAdr(QString::number(static_cast<uint>(record->ExceptionAddress,16))),errMod;

    QString tips = QObject::tr("<FONT size=4><div><b>We sincerely apologize for the mistake</b><br/></div>")+
            QObject::tr("<div>Error code:%1</div><div>Wrong address:%2</div></FONT>").arg(errCode).arg(errAdr);

    //CMessageBox::Warning(tips,QObject::tr("Error"));
    QMessageBox::critical(nullptr,"error",tips,QMessageBox::Ok);
    return EXCEPTION_EXECUTE_HANDLER;
}
